Skip to content

Custom Data Usage Guide

This guide provides detailed instructions on how to use custom data for model training and inference in the Dexbotic framework.

Table of Contents

Data Format Requirements

Dexdata Format

Dexbotic uses the Dexdata format to store robotic datasets in a unified way. Your custom data needs to follow this format:

Dataset Directory Structure

your_custom_dataset/
    index_cache.json   # Global index file (auto-generated)
    episode1.jsonl     # Data for the first episode
    episode2.jsonl     # Data for the second episode
    ...

Episode Data Format

Each .jsonl file contains data for one robot episode, with each line corresponding to one frame:

json
{
    "images_1": {"type": "video", "url": "url1", "frame_idx": 21}, 
    "images_2": {"type": "video", "url": "url2", "frame_idx": 21},
    "images_3": {"type": "video", "url": "url3", "frame_idx": 21},
    "state": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 1.0],
    "prompt": "open the door",
    "is_robot": true
}

Field Specifications

  • RGB data

    • Stored under keys like images_*.
    • Multiple views can be added (images_1, images_2, …). The usage order can be specified in the data configuration (DataConfig) data_keys, and you can also specify to use only a subset of the images.
    • We recommend using the Main View in images_1, the Left Hand View in images_2, and the Right Hand View in images_3.
    • Data can be video format, represented as {"type": "video", "url": "video_url", "frame_idx": xx}.
    • Data can also be image format, represented as {"type": "image", "url": "image_url"}.
  • Robot state

    • Stored under the state key.
    • Typically 7-dimensional: 3D position + 3D rotation + 1 gripper
    • By default, actions are constructed online using built-in dataset transforms.
    • Pre-processed actions can also be stored explicitly under the action key.
  • Text data

    • Prompts are stored in the prompt key.
    • Responses can be specified in two ways:
      • Directly: via the answer key.
      • Indirectly: leave answer empty, and Dexdata will use ActionNormAnd2String to convert actions into discretized textual responses.
  • Robot vs. general data [Important]

    • The is_robot flag distinguishes robot data (true) from general data (false).

Dataset Preparation

1. Data Collection

Collect your robot data, ensuring it includes:

  • Image data
  • Robot state information (state field)
  • Corresponding text instructions (prompt field)

2. Data Conversion

Convert your raw data to Dexdata format:

python
import json
import os

def convert_to_dexdata_format(episode_data, output_dir):
    """
    Convert raw data to Dexdata format
    
    Args:
        episode_data: List containing episode data
        output_dir: Output directory
    """
    os.makedirs(output_dir, exist_ok=True)
    
    for i, episode in enumerate(episode_data):
        episode_file = os.path.join(output_dir, f"episode{i+1}.jsonl")
        
        with open(episode_file, 'w', encoding='utf-8') as f:
            for frame in episode:
                # Convert each frame of data
                dexdata_frame = {
                    "images_1": {
                        "type": "image", 
                        "url": frame['image_path']
                    },
                    "state": frame['robot_state'],
                    "prompt": frame['instruction'],
                    "is_robot": True
                }
                
                # Write to jsonl file (one JSON object per line)
                f.write(json.dumps(dexdata_frame, ensure_ascii=False) + '\n')

Dataset Registration

Create Data Source File

Create your data source file in the dexbotic/data/data_source/ directory:

python
# dexbotic/data/data_source/my_custom_dataset.py

from dexbotic.data.data_source.register import register_dataset
import math

# Define your dataset
MY_CUSTOM_DATASET = {
    "my_robot_data": {
        "data_path_prefix": "", # Image path prefix
        "annotations": '/path/to/your/custom_dataset/',  # Dataset path
        "frequency": 1,  # Data sampling frequency
    },
}

# Define metadata
meta_data = {
    'non_delta_mask': [6],  # Non-delta dim index, e.g. gripper
    'periodic_mask': [3, 4, 5],  # Indices of periodic action dimensions (e.g., rotation), used for handling wrapping
    'periodic_range': 2 * math.pi  # periodic range
}

# Register dataset
register_dataset(MY_CUSTOM_DATASET, meta_data=meta_data, prefix='my_custom')

Experiment Configuration

Create Experiment File

Create your experiment file in the playground/ directory:

python
# playground/my_custom_experiment.py

from dataclasses import dataclass, field
from dexbotic.exp.cogact_exp import CogACTDataConfig, CogACTExp

@dataclass
class MyCustomDataConfig(CogACTDataConfig):
    """Data configuration"""
    dataset_name: str = field(default='my_custom_my_robot_data')  # Dataset name
    num_images: int = field(default=1)  # Number of images
    images_keys: list[str] = field(default_factory=lambda: ['images_1'])  # Image fields

@dataclass
class MyCustomExp(CogACTExp):
    """Main experiment class"""
    data_config: MyCustomDataConfig = field(default_factory=MyCustomDataConfig)

if __name__ == "__main__":
    exp = MyCustomExp()
    exp.train()  # Training

Training and Inference

1. Start Training

bash
# Use torchrun for distributed training
torchrun playground/my_custom_experiment.py

2. Monitor Training Process

During training, the system will:

  • Automatically compute action normalization parameters and save to norm_assets/ directory
  • Periodically save model checkpoints to output_dir
  • Use Weights & Biases to record training metrics (if wandb is configured)

3. Inference Service

After training is complete, start the inference service:

python
# Modify experiment file, configure trained model path
from dexbotic.exp.cogact_exp import InferenceConfig

@dataclass
class MyCustomInferenceConfig(InferenceConfig):
    """Inference configuration"""
    model_name_or_path: str = field(default='/path/to/trained/model')  # Trained model path
    port: int = field(default=7891)  # Inference service port

@dataclass
class MyCustomExp(CogACTExp):
    """Main experiment class"""
    data_config: MyCustomDataConfig = field(default_factory=MyCustomDataConfig)
    inference_config: MyCustomInferenceConfig = field(default_factory=MyCustomInferenceConfig)

if __name__ == "__main__":
    exp = MyCustomExp()
    exp.inference()  # Start inference service
bash
# Start inference service
python playground/my_custom_experiment.py --task inference

4. Use Inference API

bash
# Send inference request
curl -X POST http://localhost:7891/process_frame \
  -F "text=Grab the red object" \
  -F "image=@/path/to/your/image.jpg"

# Response example
# {"response": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 1.0]}